<!-- templates/admin/ops_dashboard.html -->
{% extends "base.html" %}

{% block title %}系统运维 - 酒店管理系统{% endblock %}

{% block extra_css %}
<style>
.metric-card {
    @apply bg-white rounded-lg shadow p-6 transition-all duration-300 hover:shadow-lg;
}
.health-indicator {
    @apply inline-flex items-center px-3 py-1 rounded-full text-sm font-medium;
}
.health-good { @apply bg-green-100 text-green-800; }
.health-warning { @apply bg-yellow-100 text-yellow-800; }
.health-critical { @apply bg-red-100 text-red-800; }
.progress-bar {
    @apply w-full bg-gray-200 rounded-full h-2.5;
}
.progress-fill {
    @apply h-2.5 rounded-full transition-all duration-500;
}
</style>
{% endblock %}

{% block content %}
<div class="container mx-auto px-4 py-8">
    <!-- 页面标题 -->
    <div class="mb-8">
        <h1 class="text-3xl font-bold text-gray-800">系统运维管理</h1>
        <p class="text-gray-600 mt-2">实时监控系统状态，管理备份和执行维护任务</p>
    </div>

    <!-- 系统健康状态 -->
    <div class="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-8">
        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-2">系统健康</h3>
            <div id="health-status" class="text-2xl font-bold">检查中...</div>
            <div id="health-score" class="text-sm text-gray-500">健康评分: -</div>
        </div>

        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-2">CPU使用率</h3>
            <div id="cpu-usage" class="text-2xl font-bold">-</div>
            <div class="progress-bar mt-2">
                <div id="cpu-progress" class="progress-fill bg-blue-500" style="width: 0%"></div>
            </div>
        </div>

        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-2">内存使用</h3>
            <div id="memory-usage" class="text-2xl font-bold">-</div>
            <div class="progress-bar mt-2">
                <div id="memory-progress" class="progress-fill bg-green-500" style="width: 0%"></div>
            </div>
        </div>

        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-2">磁盘使用</h3>
            <div id="disk-usage" class="text-2xl font-bold">-</div>
            <div class="progress-bar mt-2">
                <div id="disk-progress" class="progress-fill bg-purple-500" style="width: 0%"></div>
            </div>
        </div>
    </div>

    <!-- 运维操作卡片 -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
        <!-- 备份管理 -->
        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-4">备份管理</h3>
            <div class="space-y-3">
                <button onclick="createBackup()" class="w-full bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded transition-colors">
                    创建备份
                </button>
                <button onclick="loadBackups()" class="w-full bg-gray-500 hover:bg-gray-600 text-white py-2 px-4 rounded transition-colors">
                    刷新备份列表
                </button>
                <button onclick="cleanupBackups()" class="w-full bg-orange-500 hover:bg-orange-600 text-white py-2 px-4 rounded transition-colors">
                    清理旧备份
                </button>
            </div>
        </div>

        <!-- 系统监控 -->
        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-4">系统监控</h3>
            <div class="space-y-3">
                <button onclick="startMonitoring()" class="w-full bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded transition-colors">
                    启动监控
                </button>
                <button onclick="stopMonitoring()" class="w-full bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded transition-colors">
                    停止监控
                </button>
                <div class="text-sm text-gray-500" id="monitoring-status">
                    监控状态: 未运行
                </div>
            </div>
        </div>

        <!-- 服务检查 -->
        <div class="metric-card">
            <h3 class="text-lg font-semibold text-gray-700 mb-4">服务状态</h3>
            <div class="space-y-2" id="services-status">
                <div class="flex justify-between items-center">
                    <span>MySQL</span>
                    <span class="health-indicator health-good">运行中</span>
                </div>
                <div class="flex justify-between items-center">
                    <span>Web服务</span>
                    <span class="health-indicator health-good">运行中</span>
                </div>
            </div>
        </div>
    </div>

    <!-- 备份列表 -->
    <div class="metric-card">
        <div class="flex justify-between items-center mb-4">
            <h3 class="text-lg font-semibold text-gray-700">备份历史</h3>
            <span class="text-sm text-gray-500" id="backup-count">加载中...</span>
        </div>
        <div class="overflow-x-auto">
            <table class="min-w-full divide-y divide-gray-200">
                <thead>
                    <tr>
                        <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">备份名称</th>
                        <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">创建时间</th>
                        <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">类型</th>
                        <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">大小</th>
                        <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">操作</th>
                    </tr>
                </thead>
                <tbody id="backups-list" class="divide-y divide-gray-200">
                    <!-- 备份列表将通过JavaScript动态加载 -->
                </tbody>
            </table>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
// 全局加载状态管理
let isLoading = false;

// 显示加载状态
function showLoading(message = '处理中...') {
    if (isLoading) return;
    isLoading = true;
    
    const loadingDiv = document.createElement('div');
    loadingDiv.id = 'loading-overlay';
    loadingDiv.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
    loadingDiv.innerHTML = `
        <div class="bg-white rounded-lg p-6 shadow-xl">
            <div class="flex items-center space-x-3">
                <svg class="animate-spin h-8 w-8 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
                <span class="text-lg font-medium text-gray-700">${message}</span>
            </div>
        </div>
    `;
    document.body.appendChild(loadingDiv);
}

// 隐藏加载状态
function hideLoading() {
    isLoading = false;
    const loadingDiv = document.getElementById('loading-overlay');
    if (loadingDiv) {
        loadingDiv.remove();
    }
}

// 显示通知
function showNotification(message, type = 'info') {
    const colors = {
        'success': 'bg-green-500',
        'error': 'bg-red-500',
        'info': 'bg-blue-500',
        'warning': 'bg-yellow-500'
    };
    
    const notification = document.createElement('div');
    notification.className = `fixed top-4 right-4 ${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg z-50 transform transition-all duration-300`;
    notification.textContent = message;
    document.body.appendChild(notification);
    
    setTimeout(() => {
        notification.style.opacity = '0';
        setTimeout(() => notification.remove(), 300);
    }, 3000);
}

// 系统健康状态监控(优化版 - 带缓存)
let healthCache = null;
let healthCacheTime = 0;
const CACHE_DURATION = 5000; // 5秒缓存

async function loadSystemHealth(forceRefresh = false) {
    // 检查缓存
    const now = Date.now();
    if (!forceRefresh && healthCache && (now - healthCacheTime < CACHE_DURATION)) {
        updateHealthUI(healthCache);
        return;
    }
    
    try {
        const response = await fetch('/admin/system-ops/health');
        const data = await response.json();

        if (data.success) {
            healthCache = data.health;
            healthCacheTime = now;
            updateHealthUI(data.health);
        } else {
            console.error('获取健康状态失败:', data.message);
            document.getElementById('health-status').textContent = '获取失败';
            document.getElementById('health-status').className = 'text-2xl font-bold text-red-600';
        }
    } catch (error) {
        console.error('加载健康状态出错:', error);
        document.getElementById('health-status').textContent = '加载失败';
        document.getElementById('health-status').className = 'text-2xl font-bold text-red-600';
    }
}

// 更新健康状态UI
function updateHealthUI(health) {
    // 更新健康状态
    const healthEl = document.getElementById('health-status');
    const scoreEl = document.getElementById('health-score');

    if (health.status) {
        healthEl.textContent = health.status;
        healthEl.className = `text-2xl font-bold ${
            health.status_color === 'green' ? 'text-green-600' :
            health.status_color === 'yellow' ? 'text-yellow-600' : 'text-red-600'
        }`;
        scoreEl.textContent = `健康评分: ${health.health_score}`;
    }

    // 更新CPU使用率
    if (health.cpu && health.cpu.usage_percent !== undefined) {
        const cpuEl = document.getElementById('cpu-usage');
        const cpuProgress = document.getElementById('cpu-progress');
        const cpuPercent = health.cpu.usage_percent;
        cpuEl.textContent = `${cpuPercent}%`;
        cpuProgress.style.width = `${cpuPercent}%`;
        cpuProgress.className = `progress-fill ${
            cpuPercent > 80 ? 'bg-red-500' :
            cpuPercent > 60 ? 'bg-yellow-500' : 'bg-blue-500'
        }`;
    }

    // 更新内存使用率
    if (health.memory && health.memory.usage_percent !== undefined) {
        const memoryEl = document.getElementById('memory-usage');
        const memoryProgress = document.getElementById('memory-progress');
        const memoryPercent = health.memory.usage_percent;
        memoryEl.textContent = `${memoryPercent}%`;
        memoryProgress.style.width = `${memoryPercent}%`;
        memoryProgress.className = `progress-fill ${
            memoryPercent > 85 ? 'bg-red-500' :
            memoryPercent > 70 ? 'bg-yellow-500' : 'bg-green-500'
        }`;
    }

    // 更新磁盘使用率
    if (health.disk && health.disk.usage_percent !== undefined) {
        const diskEl = document.getElementById('disk-usage');
        const diskProgress = document.getElementById('disk-progress');
        const diskPercent = health.disk.usage_percent;
        diskEl.textContent = `${diskPercent}%`;
        diskProgress.style.width = `${diskPercent}%`;
        diskProgress.className = `progress-fill ${
            diskPercent > 90 ? 'bg-red-500' :
            diskPercent > 80 ? 'bg-yellow-500' : 'bg-purple-500'
        }`;
    }
}

// 备份管理功能(优化版 - 带进度反馈)
async function createBackup() {
    if (isLoading) {
        showNotification('有任务正在进行中,请稍候', 'warning');
        return;
    }
    
    if (!confirm('确定要创建备份吗?这可能需要几分钟时间。')) {
        return;
    }
    
    try {
        showLoading('正在创建备份,请稍候...');
        
        const response = await fetch('/admin/system-ops/backup', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                type: 'full',
                include_logs: true
            })
        });

        const data = await response.json();
        hideLoading();

        if (data.success) {
            showNotification('备份创建成功!', 'success');
            loadBackups(true); // 强制刷新
        } else {
            showNotification('备份创建失败: ' + data.message, 'error');
        }
    } catch (error) {
        hideLoading();
        console.error('创建备份出错:', error);
        showNotification('创建备份失败', 'error');
    }
}

// 备份列表缓存
let backupCache = null;
let backupCacheTime = 0;

async function loadBackups(forceRefresh = false) {
    // 检查缓存
    const now = Date.now();
    if (!forceRefresh && backupCache && (now - backupCacheTime < CACHE_DURATION)) {
        updateBackupsUI(backupCache);
        return;
    }
    
    try {
        console.log('正在加载备份列表...');
        const response = await fetch('/admin/system-ops/backups');
        console.log('API响应状态:', response.status);
        
        const data = await response.json();
        console.log('备份列表数据:', data);

        if (data.success) {
            backupCache = data.backups;
            backupCacheTime = now;
            console.log(`成功获取 ${data.backups.length} 个备份`);
            updateBackupsUI(data.backups);
        } else {
            console.error('获取备份列表失败:', data.message);
            showNotification('获取备份列表失败: ' + data.message, 'error');
        }
    } catch (error) {
        console.error('加载备份列表出错:', error);
        showNotification('加载备份列表失败', 'error');
    }
}

function updateBackupsUI(backups) {
    const container = document.getElementById('backups-list');
    const countEl = document.getElementById('backup-count');
    
    console.log('更新UI,备份数量:', backups.length);

    countEl.textContent = `共 ${backups.length} 个备份`;

    if (backups.length === 0) {
        container.innerHTML = `
            <tr>
                <td colspan="5" class="px-4 py-4 text-center text-gray-500">
                    暂无备份
                </td>
            </tr>
        `;
        return;
    }

    container.innerHTML = backups.map((backup, index) => {
        console.log(`备份 ${index}:`, backup);
        const dateStr = backup.created_at ? new Date(backup.created_at).toLocaleString('zh-CN') : '未知时间';
        return `
            <tr>
                <td class="px-4 py-4 text-sm text-gray-900">${backup.name || '未知'}</td>
                <td class="px-4 py-4 text-sm text-gray-500">${dateStr}</td>
                <td class="px-4 py-4 text-sm text-gray-500">${backup.type || 'directory'}</td>
                <td class="px-4 py-4 text-sm text-gray-500">${backup.size || 'Unknown'}</td>
                <td class="px-4 py-4 text-sm">
                    <button onclick="downloadBackup('${backup.name}')" class="text-blue-600 hover:text-blue-900 mr-2">
                        下载
                    </button>
                    <button onclick="deleteBackup('${backup.name}')" class="text-red-600 hover:text-red-900">
                        删除
                    </button>
                </td>
            </tr>
        `;
    }).join('');
    
    console.log('备份列表UI更新完成');
}

async function downloadBackup(backupName) {
    try {
        // 修复：使用正确的URL路径
        window.open(`/admin/system-ops/backup/download/${backupName}`, '_blank');
    } catch (error) {
        console.error('下载备份出错:', error);
        alert('下载备份失败');
    }
}

async function deleteBackup(backupName) {
    if (isLoading) {
        showNotification('有任务正在进行中,请稍候', 'warning');
        return;
    }
    
    if (!confirm(`确定要删除备份 ${backupName} 吗？`)) {
        return;
    }

    try {
        showLoading('正在删除备份...');
        
        const response = await fetch(`/admin/system-ops/backups/delete/${backupName}`, {
            method: 'DELETE'
        });

        const data = await response.json();
        hideLoading();

        if (data.success) {
            showNotification('备份删除成功!', 'success');
            loadBackups(true); // 强制刷新
        } else {
            showNotification('备份删除失败: ' + data.message, 'error');
        }
    } catch (error) {
        hideLoading();
        console.error('删除备份出错:', error);
        showNotification('删除备份失败', 'error');
    }
}

async function cleanupBackups() {
    if (isLoading) {
        showNotification('有任务正在进行中,请稍候', 'warning');
        return;
    }
    
    if (!confirm('确定要清理旧备份吗？将保留最新的10个备份。')) {
        return;
    }

    try {
        showLoading('正在清理旧备份...');
        
        const response = await fetch('/admin/system-ops/cleanup/backups', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                keep_count: 10
            })
        });

        const data = await response.json();
        hideLoading();

        if (data.success) {
            showNotification(`清理完成: ${data.message}`, 'success');
            loadBackups(true); // 强制刷新
        } else {
            showNotification('清理失败: ' + data.message, 'error');
        }
    } catch (error) {
        hideLoading();
        console.error('清理备份出错:', error);
        showNotification('清理备份失败', 'error');
    }
}

// 监控功能
async function startMonitoring() {
    try {
        // 修复：使用正确的URL路径
        const response = await fetch('/admin/system-ops/monitoring/start', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                interval: 60
            })
        });

        const data = await response.json();

        if (data.success) {
            document.getElementById('monitoring-status').textContent = '监控状态: 运行中';
            alert('系统监控已启动');
        } else {
            alert('启动监控失败: ' + data.message);
        }
    } catch (error) {
        console.error('启动监控出错:', error);
        alert('启动监控失败');
    }
}

async function stopMonitoring() {
    try {
        // 修复：使用正确的URL路径
        const response = await fetch('/admin/system-ops/monitoring/stop', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            }
        });

        const data = await response.json();

        if (data.success) {
            document.getElementById('monitoring-status').textContent = '监控状态: 未运行';
            alert('系统监控已停止');
        } else {
            alert('停止监控失败: ' + data.message);
        }
    } catch (error) {
        console.error('停止监控出错:', error);
        alert('停止监控失败');
    }
}

// 页面加载完成后初始化(优化版 - 防抖动)
let refreshTimer = null;

document.addEventListener('DOMContentLoaded', function() {
    // 加载系统健康状态
    loadSystemHealth();

    // 加载备份列表
    loadBackups();

    // 每30秒刷新一次健康状态(使用缓存)
    refreshTimer = setInterval(() => {
        if (!isLoading) {
            loadSystemHealth();
        }
    }, 30000);
});

// 页面隐藏时暂停刷新,显示时恢复
document.addEventListener('visibilitychange', function() {
    if (document.hidden) {
        if (refreshTimer) {
            clearInterval(refreshTimer);
            refreshTimer = null;
        }
    } else {
        if (!refreshTimer) {
            loadSystemHealth(true); // 重新显示时强制刷新
            refreshTimer = setInterval(() => {
                if (!isLoading) {
                    loadSystemHealth();
                }
            }, 30000);
        }
    }
});
</script>
{% endblock %}